package club.bigtian.statusbar;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.CustomStatusBarWidget;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 状态栏文字显示组件 - 带倒计时和余额显示
 * 倒计时到期后自动刷新当前账户信息
 */
public class StatusBarTextWidget implements CustomStatusBarWidget {

    private static final String WIDGET_ID = "StatusBarTextWidget";
    private final Project project;
    private StatusBar statusBar;
    private JLabel label;

    // 倒计时相关
    private static final int DEFAULT_COUNTDOWN_SECONDS = 300; // 默认5分钟
    private int countdownTotal; // 总倒计时时间（从配置读取）
    private int countdown; // 当前倒计时
    private ScheduledExecutorService scheduler;
    private boolean isCountdownActive = true; // 倒计时是否激活

    // 余额相关
    private int currentBalance = 0; // 当前余额
    private String currentAccountId = null; // 当前账户ID
    private boolean isAccountBanned = false; // 当前账户是否被封禁

    public StatusBarTextWidget(@NotNull Project project) {
        this.project = project;
        // 从配置文件加载倒计时时间
        loadCountdownSettings();
    }

    /**
     * 从配置文件加载倒计时设置
     */
    private void loadCountdownSettings() {
        try {
            TokenConfig.Settings settings = TokenConfig.loadSettings();
            if (settings != null && settings.getCountdownSeconds() != null && settings.getCountdownSeconds() > 0) {
                countdownTotal = settings.getCountdownSeconds();
                countdown = countdownTotal;
                System.out.println("✅ 加载倒计时设置: " + countdownTotal + "秒");
            } else {
                countdownTotal = DEFAULT_COUNTDOWN_SECONDS;
                countdown = countdownTotal;
                System.out.println("⚠️ 使用默认倒计时: " + countdownTotal + "秒");
            }
        } catch (Exception e) {
            System.err.println("❌ 加载倒计时设置失败，使用默认值: " + e.getMessage());
            countdownTotal = DEFAULT_COUNTDOWN_SECONDS;
            countdown = countdownTotal;
        }
    }

    /**
     * 更新倒计时设置（外部调用）
     */
    public void updateCountdownSettings(int newCountdownSeconds) {
        if (newCountdownSeconds > 0) {
            countdownTotal = newCountdownSeconds;
            countdown = countdownTotal;
            System.out.println("✅ 倒计时已更新为: " + countdownTotal + "秒");
            // 更新UI
            ApplicationManager.getApplication().invokeLater(this::updateLabel);
        }
    }

    @Override
    public @NonNls @NotNull String ID() {
        return WIDGET_ID;
    }



    @Override
    public void install(@NotNull StatusBar statusBar) {
        this.statusBar = statusBar;
        // 启动定时器
        startCountdown();
    }

    @Override
    public void dispose() {
        // 清理资源，停止定时器
        if (scheduler != null && !scheduler.isShutdown()) {
            scheduler.shutdown();
        }
    }

    /**
     * 启动倒计时
     */
    private void startCountdown() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(() -> {
            // 在EDT线程中更新UI
            ApplicationManager.getApplication().invokeLater(() -> {
                // 只有在倒计时激活且账户未被封禁时才更新倒计时
                if (isCountdownActive && !isAccountBanned) {
                    if (countdown > 0) {
                        countdown--;
                    } else {
                        // 倒计时结束，触发刷新
                        onCountdownExpired();
                        // 重置倒计时
                        countdown = countdownTotal;
                    }
                }
                // 更新UI显示
                updateLabel();
            });
        }, 0, 1, TimeUnit.SECONDS);
    }

    /**
     * 倒计时到期时的处理
     */
    private void onCountdownExpired() {
        System.out.println("⏰ 倒计时到期，开始刷新当前账户...");
        refreshCurrentAccount();
    }

    /**
     * 获取当前正在使用的账户信息
     */
    private TokenConfig.TokenRawData getCurrentAccount() {
        try {
            // 从CredentialManager获取当前的tenantUrl和token
            CredentialManager credentialManager = new CredentialManager();
            String currentTenantUrl = credentialManager.getTenantUrl();
            String currentAuthToken = credentialManager.getAuthToken();

            if (currentTenantUrl == null || currentTenantUrl.isEmpty()) {
                System.out.println("⚠️ 未找到当前使用的账户");
                return null;
            }

            // 从tokens.json中查找匹配的账户
            java.util.List<TokenConfig.TokenRawData> tokens = TokenConfig.tryLoadTokens();
            for (TokenConfig.TokenRawData token : tokens) {
                if (currentTenantUrl.equals(token.getTenantUrl()) &&
                    currentAuthToken.equals(token.getAccessToken())) {
                    System.out.println("✅ 找到当前账户: " + token.getEmailNote());
                    currentAccountId = token.getId();
                    return token;
                }
            }

            System.out.println("⚠️ 在tokens.json中未找到匹配的账户");
            return null;
        } catch (Exception e) {
            System.err.println("❌ 获取当前账户失败: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 刷新当前账户信息
     */
    private void refreshCurrentAccount() {
        new Thread(() -> {
            try {
                TokenConfig.TokenRawData currentAccount = getCurrentAccount();
                if (currentAccount == null) {
                    System.out.println("⚠️ 无法刷新：未找到当前账户");
                    return;
                }

                // 调用刷新服务
                java.util.List<TokenConfig.TokenRawData> singleToken = new java.util.ArrayList<>();
                singleToken.add(currentAccount);

                java.util.List<TokenRefreshService.RefreshResult> results =
                    TokenRefreshService.batchRefreshAccounts(singleToken);

                if (!results.isEmpty() && results.get(0).isSuccess()) {
                    TokenRefreshService.RefreshResult result = results.get(0);

                    // 检查封禁状态 - 只有明确的封禁状态才判定为封禁
                    String banStatus = result.getBanStatus();
                    if (isAccountBanned(banStatus)) {
                        System.out.println("⚠️ 账户已被封禁，状态: " + banStatus);
                        isAccountBanned = true;
                        isCountdownActive = false; // 停止倒计时
                    } else {
                        isAccountBanned = false;
                        // 如果之前被封禁，现在解封了，重新启动倒计时
                        if (!isCountdownActive) {
                            isCountdownActive = true;
                            countdown = countdownTotal; // 重置倒计时
                        }
                    }

                    // 更新余额
                    if (result.getPortalInfo() != null && result.getPortalInfo().getCreditsBalance() != null) {
                        currentBalance = result.getPortalInfo().getCreditsBalance();
                        System.out.println("✅ 刷新成功，当前余额: " + currentBalance + ", 封禁状态: " + banStatus);

                        // 更新配置文件
                        updateTokenInConfig(result);

                        // 只有在未被封禁且余额不足时才切换账号
                        if (!isAccountBanned && currentBalance < 100) {
                            System.out.println("⚠️ 余额不足100，准备切换账号...");
                            switchToNextAccount();
                        }
                    }

                    // 更新UI
                    ApplicationManager.getApplication().invokeLater(this::updateLabel);
                } else {
                    System.out.println("❌ 刷新失败");
                }
            } catch (Exception e) {
                System.err.println("❌ 刷新账户失败: " + e.getMessage());
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * 更新配置文件中的token数据
     */
    private void updateTokenInConfig(TokenRefreshService.RefreshResult result) {
        try {
            java.util.List<TokenConfig.TokenRawData> tokens = TokenConfig.tryLoadTokens();

            for (TokenConfig.TokenRawData token : tokens) {
                if (token.getId().equals(result.getId())) {
                    token.setBanStatus(result.getBanStatus());
                    if (result.getPortalInfo() != null) {
                        TokenConfig.PortalInfo portalInfo = new TokenConfig.PortalInfo();
                        portalInfo.setCreditsBalance(result.getPortalInfo().getCreditsBalance());
                        portalInfo.setExpiryDate(result.getPortalInfo().getExpiryDate());
                        token.setPortalInfo(portalInfo);
                    }
                    token.setUpdatedAt(java.time.Instant.now().toString());
                    break;
                }
            }

            TokenConfig.saveTokens(tokens);
        } catch (Exception e) {
            System.err.println("❌ 更新配置文件失败: " + e.getMessage());
        }
    }

    /**
     * 切换到下一个可用账号（优先使用快要过期的账号）
     */
    private void switchToNextAccount() {
        try {
            System.out.println("🔄 开始查找快要过期的账号...");
            System.out.println("📊 当前账号ID: " + currentAccountId);
            System.out.println("📊 当前余额: " + currentBalance);

            // 加载所有账号
            java.util.List<TokenConfig.TokenRawData> tokens = TokenConfig.tryLoadTokens();
            if (tokens == null || tokens.isEmpty()) {
                System.out.println("⚠️ 没有可用的账号");
                ApplicationManager.getApplication().invokeLater(() ->
                    NotificationUtil.showWarning(project, "无可用账号", "tokens.json中没有账号数据"));
                return;
            }

            System.out.println("📊 总共有 " + tokens.size() + " 个账号");

            // 找到快要过期的账号（过期时间最早的账号，排除当前账号）
            TokenConfig.TokenRawData bestAccount = null;
            String earliestExpiryDate = null;

            for (TokenConfig.TokenRawData token : tokens) {
                String tokenId = token.getId();
                String emailNote = token.getEmailNote();
                String banStatus = token.getBanStatus();
                Integer balance = (token.getPortalInfo() != null) ? token.getPortalInfo().getCreditsBalance() : null;
                String expiryDate = (token.getPortalInfo() != null) ? token.getPortalInfo().getExpiryDate() : null;

                System.out.println(String.format("  检查账号: %s (ID: %s, 状态: %s, 余额: %s, 过期时间: %s)",
                    emailNote, tokenId, banStatus, balance, expiryDate));

                // 跳过当前账号
                if (currentAccountId != null && tokenId != null && tokenId.equals(currentAccountId)) {
                    System.out.println("    ⏭️ 跳过（当前账号）");
                    continue;
                }

                // 跳过被封禁的账号
                if ("BANNED".equals(banStatus) || "FORBIDDEN".equals(banStatus)) {
                    System.out.println("    ⏭️ 跳过（已封禁）");
                    continue;
                }

                // 跳过余额不足的账号
                if (balance == null || balance < 100) {
                    System.out.println("    ⏭️ 跳过（余额不足）");
                    continue;
                }

                // 选择过期时间最早的账号
                if (expiryDate != null) {
                    if (earliestExpiryDate == null || expiryDate.compareTo(earliestExpiryDate) < 0) {
                        earliestExpiryDate = expiryDate;
                        bestAccount = token;
                        System.out.println("    ✅ 当前最佳账号（过期时间: " + expiryDate + ", 余额: " + balance + "）");
                    }
                } else {
                    // 如果没有过期时间，但有余额，也可以作为候选
                    if (bestAccount == null) {
                        bestAccount = token;
                        System.out.println("    ✅ 候选账号（无过期时间，余额: " + balance + "）");
                    }
                }
            }

            if (bestAccount == null) {
                System.out.println("⚠️ 没有找到可切换的账号");
                ApplicationManager.getApplication().invokeLater(() ->
                    NotificationUtil.showWarning(project, "无可用账号", "所有账号余额都不足或已被封禁"));
                return;
            }

            // 获取最终账号信息
            int finalBalance = (bestAccount.getPortalInfo() != null && bestAccount.getPortalInfo().getCreditsBalance() != null)
                ? bestAccount.getPortalInfo().getCreditsBalance() : 0;
            String finalExpiryDate = (bestAccount.getPortalInfo() != null)
                ? bestAccount.getPortalInfo().getExpiryDate() : "未知";

            // 切换到新账号
            System.out.println("✅ 找到最佳账号: " + bestAccount.getEmailNote() +
                ", 余额: " + finalBalance + ", 过期时间: " + finalExpiryDate);

            CredentialManager credentialManager = new CredentialManager();
            credentialManager.reflectionSaveCredentials(
                bestAccount.getTenantUrl(),
                bestAccount.getAccessToken()
            );

            // 更新当前余额和账号ID
            currentBalance = finalBalance;
            currentAccountId = bestAccount.getId();

            // 更新UI
            ApplicationManager.getApplication().invokeLater(this::updateLabel);

            // 显示通知
            String finalEmailNote = bestAccount.getEmailNote();
            String displayExpiryDate = finalExpiryDate;
            ApplicationManager.getApplication().invokeLater(() ->
                NotificationUtil.showSuccess(project, "账号已切换",
                    String.format("已切换到: %s\n余额: %d\n过期时间: %s",
                        finalEmailNote, finalBalance, displayExpiryDate)));

        } catch (Exception e) {
            System.err.println("❌ 切换账号失败: " + e.getMessage());
            e.printStackTrace();
            ApplicationManager.getApplication().invokeLater(() ->
                NotificationUtil.showError(project, "切换失败", e.getMessage()));
        }
    }

    /**
     * 更新标签显示
     */
    private void updateLabel() {
        if (label != null) {
            String text;

            // 如果账户被封禁，显示封禁信息
            if (isAccountBanned) {
                text = "Augment已封禁";
                label.setForeground(JBColor.RED);
                label.setIcon(AllIcons.General.Error);
            } else {
                // 正常显示余额和倒计时
                text = String.format("余额: %d (%ds)", currentBalance, countdown);
                label.setForeground(getColorForBalance());
                label.setIcon(getIconForBalance());
            }

            label.setText(text);
            label.setToolTipText(getTooltipText());

            // 强制重绘和重新验证
            label.revalidate();
            label.repaint();

            // 如果有状态栏，也更新状态栏
            if (statusBar != null) {
                statusBar.updateWidget(WIDGET_ID);
            }
        } else {
            System.err.println("⚠️ label为null，无法更新状态栏显示");
        }
    }

    /**
     * 根据余额获取颜色
     * >15000: 绿色
     * 5000-15000: 黄色
     * <5000: 红色
     */
    private Color getColorForBalance() {
        if (currentBalance > 15000) {
            return JBColor.GREEN;
        } else if (currentBalance > 5000) {
            return JBColor.YELLOW;
        } else {
            return JBColor.RED;
        }
    }

    /**
     * 根据余额获取图标
     */
    private Icon getIconForBalance() {
        if (currentBalance > 15000) {
            return AllIcons.General.InspectionsOK;
        } else if (currentBalance > 5000) {
            return AllIcons.General.Warning;
        } else {
            return AllIcons.General.Error;
        }
    }

    /**
     * 获取颜色名称（用于提示）
     */
    private String getColorName() {
        if (currentBalance > 15000) {
            return "绿色（充足）";
        } else if (currentBalance > 5000) {
            return "黄色（中等）";
        } else {
            return "红色（不足）";
        }
    }

    /**
     * 获取提示文本
     */
    private String getTooltipText() {
        if (isAccountBanned) {
            return "当前账户已被封禁\n点击查看账户信息并切换账户";
        }
        return String.format(
            "当前余额: %d (%s)\n倒计时: %d秒\n点击查看账户信息",
            currentBalance,
            getColorName(),
            countdown
        );
    }

    /**
     * 创建状态栏组件
     */
    @Override
    public JComponent getComponent() {
        if (label == null) {
            // 初始化时尝试获取当前账户余额
            initializeBalance();

            label = new JLabel(String.format("余额: %d (%ds)", currentBalance, countdown));
            label.setForeground(getColorForBalance());
            label.setIcon(getIconForBalance());
            label.setBorder(JBUI.Borders.empty(0, 5));
            label.setToolTipText(getTooltipText());

            // 添加点击事件 - 弹出网页卡片对话框
            label.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    // 显示网页卡片对话框
                    WebCardDialog dialog = new WebCardDialog(project);
                    dialog.show();
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                    // 更新提示文字
                    label.setToolTipText(getTooltipText());
                    // 改变鼠标样式为手型
                    label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    // 恢复默认鼠标样式
                    label.setCursor(Cursor.getDefaultCursor());
                }
            });
        }
        return label;
    }

    /**
     * 初始化余额信息
     */
    private void initializeBalance() {
        try {
            TokenConfig.TokenRawData currentAccount = getCurrentAccount();
            if (currentAccount != null) {
                // 检查封禁状态 - 只有明确的封禁状态才判定为封禁
                String banStatus = currentAccount.getBanStatus();
                if (isAccountBanned(banStatus)) {
                    isAccountBanned = true;
                    isCountdownActive = false;
                    System.out.println("⚠️ 初始化时发现账户已被封禁，状态: " + banStatus);
                }

                // 获取余额
                if (currentAccount.getPortalInfo() != null) {
                    Integer balance = currentAccount.getPortalInfo().getCreditsBalance();
                    if (balance != null) {
                        currentBalance = balance;
                        System.out.println("✅ 初始化余额: " + currentBalance + ", 封禁状态: " + banStatus);

                        // 只有在未被封禁且余额不足时才切换
                        if (!isAccountBanned && currentBalance < 100) {
                            System.out.println("⚠️ 初始余额不足100，立即切换账号...");
                            new Thread(() -> {
                                try {
                                    Thread.sleep(1000); // 等待1秒，确保UI初始化完成
                                    switchToNextAccount();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }).start();
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("❌ 初始化余额失败: " + e.getMessage());
        }
    }

    /**
     * 公共方法：更新余额显示（供外部调用）
     * @param accountId 账户ID
     * @param balance 余额
     */
    public void updateBalanceDisplay(String accountId, int balance) {
        updateBalanceDisplay(accountId, balance, null);
    }

    /**
     * 公共方法：更新余额显示（供外部调用，带封禁状态）
     * @param accountId 账户ID
     * @param balance 余额
     * @param banStatus 封禁状态
     */
    public void updateBalanceDisplay(String accountId, int balance, String banStatus) {
        this.currentAccountId = accountId;
        this.currentBalance = balance;

        // 检查封禁状态 - 只有明确的封禁状态才判定为封禁
        if (isAccountBanned(banStatus)) {
            this.isAccountBanned = true;
            this.isCountdownActive = false;
            System.out.println("📊 状态栏已更新: 余额=" + balance + ", 账户ID=" + accountId + ", 状态=封禁(" + banStatus + ")");
        } else {
            // 切换到正常账户时，清除封禁状态并重新启动倒计时
            this.isAccountBanned = false;
            this.isCountdownActive = true;
            this.countdown = this.countdownTotal;
            System.out.println("📊 状态栏已更新: 余额=" + balance + ", 账户ID=" + accountId + ", 状态=正常");
            System.out.println("🔄 倒计时已重新启动: " + this.countdownTotal + "秒");
        }

        // 更新UI
        ApplicationManager.getApplication().invokeLater(this::updateLabel);
    }

    /**
     * 判断账户是否被封禁
     * 只有明确的封禁状态才返回 true，ERROR 状态返回 false
     * @param banStatus 封禁状态
     * @return true=封禁，false=正常或状态未知
     */
    private boolean isAccountBanned(String banStatus) {
        if (banStatus == null || banStatus.isEmpty()) {
            return false; // 状态未知，默认正常
        }

        if ("ACTIVE".equals(banStatus)) {
            return false; // 明确正常
        }

        if (banStatus.startsWith("ERROR")) {
            return false; // 检查失败，不判定为封禁
        }

        // 其他状态（BANNED、INVALID_TOKEN、FORBIDDEN、NOT_FOUND等）判定为封禁
        return true;
    }

    /**
     * 公共方法：刷新当前账户余额（供外部调用）
     */
    public void refreshBalance() {
        System.out.println("🔄 外部触发余额刷新");
        initializeBalance();
        ApplicationManager.getApplication().invokeLater(this::updateLabel);
    }
}

